package com.bw.lib_core.mvvm.view;

import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.DialogFragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import com.blankj.utilcode.util.LogUtils;
import com.bw.lib_core.bean.ErrorBean;
import com.bw.lib_core.bean.UIBusBean;
import com.bw.lib_core.bus.ActivityParams;
import com.bw.lib_core.mvvm.viewmodel.BaseViewModel;

import java.lang.ref.WeakReference;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public abstract
class BaseFragmentDialog<V extends ViewDataBinding, VM extends BaseViewModel> extends DialogFragment implements IView {

    protected V mDataBinding;
    protected VM mViewModel;
    private UIObserver uiObserver;


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mDataBinding = DataBindingUtil.inflate(inflater, bandingLayout(), container, false);
        return mDataBinding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initBar();
        init();
        initParam();
        initData();
        initObserver();
    }

    protected abstract void initData();

    /**
     * ViewModel创建
     * mDataBinding和生命周期管理
     * ViewModel生命周期管理
     * ViewModel 和  DataBinding 关联
     */
    private void init() {
        //ViewModel 初始化
        if (mViewModel == null) {
            //反射调用 ->
            Class<VM> modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class<VM>) ((ParameterizedType) type).getActualTypeArguments()[1];
            } else {
                modelClass = (Class<VM>) BaseViewModel.class;
            }
            mViewModel = createViewModel(modelClass);
        }
        //ViewModel 和  DataBinding 关联
        mDataBinding.setVariable(initVariableId(), mViewModel);
        //mDataBinding和生命周期管理
        mDataBinding.setLifecycleOwner(this);
        //ViewModel生命周期管理
        getLifecycle().addObserver(mViewModel);
        //关联UILiveData
        uiObserver = new UIObserver(this);
        mViewModel.getLiveData().observe(this, uiObserver);
    }

    /**
     * 创建ViewModel
     */
    private VM createViewModel(Class<VM> modelClass) {
        return new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(modelClass);
    }

    @Override
    public void initParam() {

    }

    @Override
    public void initBar() {

    }

    @Override
    public void initObserver() {

    }

    @Override
    public void startPage(Class<?> aClass) {
        startActivity(new Intent(getContext(), aClass));
    }

    @Override
    public void startPage(Class<?> aClass, Bundle bundle) {
        Intent intent = new Intent(getContext(), aClass);
        intent.putExtra("bundle", bundle);
        startActivity(intent);
    }

    @Override
    public void showLoading() {

    }

    @Override
    public void hideLoading() {

    }

    @Override
    public void showError(ErrorBean bean) {

    }

    @Override
    public void hideError() {

    }

    /**
     * UI层操作统一入口
     */
    public static class UIObserver implements Observer<UIBusBean> {
        /**
         * 弱引用
         */
        private WeakReference<BaseFragmentDialog> weakReference;

        public UIObserver(BaseFragmentDialog fragment) {
            weakReference = new WeakReference<BaseFragmentDialog>(fragment);
        }

        @Override
        public void onChanged(UIBusBean s) {
            if (weakReference.get() == null) {
                return;
            }
            switch (s.action) {
                case START_PAGE:
                    Class<?> c = (Class<?>) s.data.get(ActivityParams.CLASS_KEY);
                    weakReference.get().startPage(c);
                    break;
                case START_PAGE_BUNDLE:
                    Class<?> pClass = (Class<?>) s.data.get(ActivityParams.CLASS_KEY);
                    Bundle bundle = (Bundle) s.data.get(ActivityParams.BUNDLE_KEY);
                    weakReference.get().startPage(pClass, bundle);
                    break;
                case SHOW_LOADING:
                    weakReference.get().showLoading();
                    break;
                case HIDE_LOADING:
                    weakReference.get().hideLoading();
                    break;
                case SHOW_ERROR:
                    ErrorBean errorBean = (ErrorBean) s.data.get(ActivityParams.ERROR_KEY);
                    assert errorBean != null;
                    LogUtils.e(errorBean.message);
                    weakReference.get().showError(errorBean);
                    break;
                case HIDE_ERROR:
                    weakReference.get().hideError();
                    break;
                case FINISH_PAGE:
                    weakReference.get().getActivity().finish();
                    break;
            }
        }
    }
}
